/*
 * @Author: Tyler
 * @Date: 2025-10-13 19:45:16
 * @Description: 
 * Copyright (c) 2025 by User/Corp, All Rights Reserved.
 */
#ifndef LAYER_H
#define LAYER_H

#include <string>
#include <memory>
using namespace std;

enum class LayerType {
    INPUT,
    HIDDEN,
    CONV,
    POOLING,
    FC,
    RECURRENT,
    OUTPUT
};

// 自定义 to_string 函数
inline std::string to_string(LayerType type) {
    switch (type) {
        case LayerType::INPUT:      return "INPUT";
        case LayerType::HIDDEN:     return "HIDDEN";
        case LayerType::CONV:       return "CONV";
        case LayerType::POOLING:    return "POOLING";
        case LayerType::FC:         return "FC"; // 全连接层，其实就是隐藏层
        case LayerType::RECURRENT:  return "RECURRENT";
        case LayerType::OUTPUT:     return "OUTPUT";
        default:                    return "UNKNOWN";
    }
}

class Layer {
    public:
        Layer(int layerIndex, const LayerType& layerType, const string& activationName="", const string& lossName="") : layerIndex(layerIndex), activationName(activationName), lossName(lossName) {
            if (activationName == "") {
                throw invalid_argument("Activation name cannot be empty.");
            }
            if (lossName == "") {
                throw invalid_argument("Loss name cannot be empty.");
            }
        }
        ~Layer() {};
        const int getLayerIndex() const {
            return layerIndex;
        }
        const LayerType& getLayerType() const {
            return layerType;
        }
        void setLayerType(const LayerType& layerType) {
            this->layerType = layerType;
        }
        const shared_ptr<Layer>& getPrevLayer() const {
            return prevLayer;
        }
        const shared_ptr<Layer>& getNextLayer() const {
            return nextLayer;
        }
        virtual void setPrevLayer(const shared_ptr<Layer>& prevLayer) {
        }
        virtual void setNextLayer(const shared_ptr<Layer>& nextLayer) {
        }
        const string& getActivationName() const {
            return activationName;
        }
        const string& getLossName() const {
            return lossName;
        }
    
    protected:
        int layerIndex;
        LayerType layerType;
        shared_ptr<Layer> prevLayer;
        shared_ptr<Layer> nextLayer;
        string activationName;
        string lossName;
};

#endif // LAYER_H
